﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common.Threads
{
    public class ThreadPoolHelper : WaitHelper
    {
        private static object lockObj = new object();
        /// <summary>
        /// ThreadPool的回调支持方法
        /// </summary>
        /// <param name="act">要执行的方法</param>
        /// <param name="callBackAct">回调方法</param>
        public static void Callback(Action act, Action callBackAct)
        {
            ThreadPool.QueueUserWorkItem(t =>
            {
                act.Invoke();
                callBackAct.BeginInvoke(null, null);
            });
        }
        /// <summary>
        /// ThreadPool的返回支持方法
        /// </summary>
        /// <param name="func"></param>
        public static Func<T> WithReturn<T>(Func<T> func)
        {
            T t = default(T);
            ManualResetEvent mre = new ManualResetEvent(false);

            ThreadPool.QueueUserWorkItem(o =>
            {
                t = func.Invoke();
                mre.Set();
            });

            return () =>
            {
                mre.WaitOne();
                return t;
            };
        }
        /// <summary>
        /// ThreadPool的回调+值返回方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="act"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static Func<T> Callback<T>(Action act, Func<T> func)
        {
            return WithReturn(() =>
            {
                act.Invoke();
                return func.Invoke();
            });
        }
        public override void Wait(int MaxThread,params Action[] acts)
        {
            base.totalQty = acts.Length;
            base.successQty = 0;
            ThreadPool.SetMaxThreads(MaxThread, MaxThread);
            foreach (Action act in acts)
            {
                ThreadPool.QueueUserWorkItem(t =>
                {
                    act.Invoke();
                    lock (lockObj)
                    {
                        base.successQty++;
                    }
                });
            }
        }
    }
}
